/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8                               :vi │
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2022 Justine Alexandra Roberts Tunney                              │
│                                                                              │
│ Permission to use, copy, modify, and/or distribute this software for         │
│ any purpose with or without fee is hereby granted, provided that the         │
│ above copyright notice and this permission notice appear in all copies.      │
│                                                                              │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
│ PERFORMANCE OF THIS SOFTWARE.                                                │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "blink/modrm.h"
#include "blink/x86.h"
#include "test/test.h"

int error;
struct XedDecodedInst xedd;

void SetUp(void) {
}

void TearDown(void) {
}

TEST(x86, testPopR10) {
  DecodeInstruction(&xedd, "\115\132\0\0", 4, XED_MODE_LONG);
  ASSERT_EQ(2, xedd.length);
  ASSERT_EQ(0132, Opcode(xedd.op.rde));
  ASSERT_EQ(0, Osz(xedd.op.rde));
  ASSERT_EQ(0, Asz(xedd.op.rde));
  ASSERT_EQ(0, Rep(xedd.op.rde));
  ASSERT_EQ(1, Rex(xedd.op.rde));
  ASSERT_EQ(1, Rexb(xedd.op.rde));
  ASSERT_EQ(1, Rexw(xedd.op.rde));
  ASSERT_EQ(1, Rexr(xedd.op.rde));
  ASSERT_EQ(0, Rexx(xedd.op.rde));
  ASSERT_EQ(0, Sego(xedd.op.rde));
  ASSERT_EQ(XED_MODE_LONG, Mode(xedd.op.rde));
  ASSERT_EQ(XED_MODE_LONG, Eamode(xedd.op.rde));
}

TEST(x86, tesRepzCmpsb) {
  DecodeInstruction(&xedd, "\363\246\0\0", 4, XED_MODE_LONG);
  ASSERT_EQ(2, xedd.length);
  ASSERT_EQ(0246, Opcode(xedd.op.rde));
  ASSERT_EQ(0, Osz(xedd.op.rde));
  ASSERT_EQ(0, Asz(xedd.op.rde));
  ASSERT_EQ(3, Rep(xedd.op.rde));
  ASSERT_EQ(0, Rex(xedd.op.rde));
  ASSERT_EQ(0, Rexb(xedd.op.rde));
  ASSERT_EQ(0, Rexw(xedd.op.rde));
  ASSERT_EQ(0, Rexr(xedd.op.rde));
  ASSERT_EQ(0, Rexx(xedd.op.rde));
  ASSERT_EQ(0, Sego(xedd.op.rde));
  ASSERT_EQ(XED_MODE_LONG, Mode(xedd.op.rde));
  ASSERT_EQ(XED_MODE_LONG, Eamode(xedd.op.rde));
}

int ild(const char *p, size_t n) {
  error = DecodeInstruction(&xedd, p, n, XED_MODE_LONG);
  return error == XED_ERROR_NONE ? xedd.length : -error;
}

int ildreal(const char *p, size_t n) {
  error = DecodeInstruction(&xedd, p, n, XED_MODE_REAL);
  return error == XED_ERROR_NONE ? xedd.length : -error;
}

int ildlegacy(const char *p, size_t n) {
  error = DecodeInstruction(&xedd, p, n, XED_MODE_LEGACY);
  return error == XED_ERROR_NONE ? xedd.length : -error;
}

TEST(ild, test86) {
  EXPECT_EQ(6, ild("\017\202\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\017\203\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\017\204\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\017\205\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\017\206\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\017\207\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\017\210\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\017\211\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\017\215\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\017\216\000\000\000\000", 6));
  EXPECT_EQ(4, ild("@\210k\000", 4));
  EXPECT_EQ(4, ild("@\210s\000", 4));
  EXPECT_EQ(4, ild("@\210w\000", 4));
  EXPECT_EQ(4, ild("@\210{\000", 4));
  EXPECT_EQ(3, ild("@\210\305", 3));
  EXPECT_EQ(3, ild("@\210\306", 3));
  EXPECT_EQ(3, ild("@\210\307", 3));
  EXPECT_EQ(3, ild("@\210\316", 3));
  EXPECT_EQ(3, ild("@\210\326", 3));
  EXPECT_EQ(3, ild("@\210\327", 3));
  EXPECT_EQ(3, ild("@\210\350", 3));
  EXPECT_EQ(3, ild("@\210\352", 3));
  EXPECT_EQ(3, ild("@\210\360", 3));
  EXPECT_EQ(3, ild("@\210\361", 3));
  EXPECT_EQ(3, ild("@\210\362", 3));
  EXPECT_EQ(3, ild("@\210\367", 3));
  EXPECT_EQ(3, ild("@\210\371", 3));
  EXPECT_EQ(3, ild("@\210\372", 3));
  EXPECT_EQ(3, ild("@\2120", 3));
  EXPECT_EQ(4, ild("@\212k\000", 4));
  EXPECT_EQ(4, ild("@\212p\000", 4));
  EXPECT_EQ(4, ild("@\212s\000", 4));
  EXPECT_EQ(4, ild("@\212w\000", 4));
  EXPECT_EQ(4, ild("@\212{\000", 4));
  EXPECT_EQ(4, ild("@\212}\000", 4));
  EXPECT_EQ(3, ild("@\266\000", 3));
  EXPECT_EQ(2, ild("AT", 2));
  EXPECT_EQ(2, ild("AU", 2));
  EXPECT_EQ(2, ild("AV", 2));
  EXPECT_EQ(2, ild("AW", 2));
  EXPECT_EQ(2, ild("AX", 2));
  EXPECT_EQ(2, ild("A\134", 2));
  EXPECT_EQ(2, ild("A]", 2));
  EXPECT_EQ(2, ild("A^", 2));
  EXPECT_EQ(2, ild("A_", 2));
  EXPECT_EQ(4, ild("A\210P\000", 4));
  EXPECT_EQ(3, ild("A\210\300", 3));
  EXPECT_EQ(3, ild("A\210\301", 3));
  EXPECT_EQ(3, ild("A\210\302", 3));
  EXPECT_EQ(3, ild("A\210\303", 3));
  EXPECT_EQ(3, ild("A\210\316", 3));
  EXPECT_EQ(3, ild("A\210\362", 3));
  EXPECT_EQ(7, ild("A\211\210\000\000\000\000", 7));
  EXPECT_EQ(3, ild("A\211\300", 3));
  EXPECT_EQ(3, ild("A\211\301", 3));
  EXPECT_EQ(3, ild("A\211\304", 3));
  EXPECT_EQ(3, ild("A\211\305", 3));
  EXPECT_EQ(3, ild("A\211\306", 3));
  EXPECT_EQ(3, ild("A\211\307", 3));
  EXPECT_EQ(3, ild("A\211\310", 3));
  EXPECT_EQ(3, ild("A\211\313", 3));
  EXPECT_EQ(3, ild("A\211\320", 3));
  EXPECT_EQ(3, ild("A\211\323", 3));
  EXPECT_EQ(3, ild("A\211\326", 3));
  EXPECT_EQ(3, ild("A\211\327", 3));
  EXPECT_EQ(3, ild("A\211\334", 3));
  EXPECT_EQ(3, ild("A\211\350", 3));
  EXPECT_EQ(3, ild("A\211\362", 3));
  EXPECT_EQ(3, ild("A\211\364", 3));
  EXPECT_EQ(3, ild("A\211\365", 3));
  EXPECT_EQ(3, ild("A\211\370", 3));
  EXPECT_EQ(3, ild("A\211\373", 3));
  EXPECT_EQ(4, ild("A\212\004\000", 4));
  EXPECT_EQ(4, ild("A\212\004\004", 4));
  EXPECT_EQ(4, ild("A\212\014\024", 4));
  EXPECT_EQ(7, ild("A\213\200\000\000\000\000", 7));
  EXPECT_EQ(6, ild("A\270\000\000\000\000", 6));
  EXPECT_EQ(6, ild("A\271\000\000\000\000", 6));
  EXPECT_EQ(6, ild("A\274\000\000\000\000", 6));
  EXPECT_EQ(6, ild("A\275\000\000\000\000", 6));
  EXPECT_EQ(6, ild("A\276\000\000\000\000", 6));
  EXPECT_EQ(6, ild("A\277\000\000\000\000", 6));
  EXPECT_EQ(4, ild("A\306\000\000", 4));
  EXPECT_EQ(5, ild("A\306\004$\000", 5));
  EXPECT_EQ(3, ild("A\323\340", 3));
  EXPECT_EQ(4, ild("A\377\024\304", 4));
  EXPECT_EQ(4, ild("B\210\004\007", 4));
  EXPECT_EQ(4, ild("B\212\004\006", 4));
  EXPECT_EQ(4, ild("B\212\024\000", 4));
  EXPECT_EQ(8, ild("B\213\024\215\000\000\000\000", 8));
  EXPECT_EQ(5, ild("C\306\004\016\000", 5));
  EXPECT_EQ(4, ild("D\210@\000", 4));
  EXPECT_EQ(4, ild("D\210C\000", 4));
  EXPECT_EQ(4, ild("D\210G\000", 4));
  EXPECT_EQ(4, ild("D\210K\000", 4));
  EXPECT_EQ(4, ild("D\210S\000", 4));
  EXPECT_EQ(4, ild("D\210c\000", 4));
  EXPECT_EQ(3, ild("D\210\300", 3));
  EXPECT_EQ(3, ild("D\210\302", 3));
  EXPECT_EQ(3, ild("D\210\305", 3));
  EXPECT_EQ(3, ild("D\210\306", 3));
  EXPECT_EQ(3, ild("D\210\310", 3));
  EXPECT_EQ(3, ild("D\210\311", 3));
  EXPECT_EQ(3, ild("D\210\312", 3));
  EXPECT_EQ(3, ild("D\210\315", 3));
  EXPECT_EQ(3, ild("D\210\316", 3));
  EXPECT_EQ(3, ild("D\210\320", 3));
  EXPECT_EQ(3, ild("D\210\322", 3));
  EXPECT_EQ(3, ild("D\210\331", 3));
  EXPECT_EQ(3, ild("D\210\350", 3));
  EXPECT_EQ(5, ild("D\211D$\000", 5));
  EXPECT_EQ(7, ild("D\211\211\000\000\000\000", 7));
  EXPECT_EQ(3, ild("D\211\300", 3));
  EXPECT_EQ(3, ild("D\211\301", 3));
  EXPECT_EQ(3, ild("D\211\302", 3));
  EXPECT_EQ(3, ild("D\211\310", 3));
  EXPECT_EQ(3, ild("D\211\316", 3));
  EXPECT_EQ(3, ild("D\211\331", 3));
  EXPECT_EQ(3, ild("D\211\340", 3));
  EXPECT_EQ(3, ild("D\211\341", 3));
  EXPECT_EQ(3, ild("D\211\342", 3));
  EXPECT_EQ(3, ild("D\211\346", 3));
  EXPECT_EQ(3, ild("D\211\347", 3));
  EXPECT_EQ(3, ild("D\211\350", 3));
  EXPECT_EQ(3, ild("D\211\351", 3));
  EXPECT_EQ(3, ild("D\211\352", 3));
  EXPECT_EQ(3, ild("D\211\357", 3));
  EXPECT_EQ(3, ild("D\211\362", 3));
  EXPECT_EQ(3, ild("D\211\367", 3));
  EXPECT_EQ(3, ild("D\211\372", 3));
  EXPECT_EQ(3, ild("D\211\377", 3));
  EXPECT_EQ(3, ild("D\212\001", 3));
  EXPECT_EQ(4, ild("D\212C\000", 4));
  EXPECT_EQ(4, ild("D\212F\000", 4));
  EXPECT_EQ(4, ild("D\212G\000", 4));
  EXPECT_EQ(4, ild("D\212N\000", 4));
  EXPECT_EQ(4, ild("D\212O\000", 4));
  EXPECT_EQ(4, ild("D\212S\000", 4));
  EXPECT_EQ(4, ild("D\212W\000", 4));
  EXPECT_EQ(4, ild("D\213\004$", 4));
  EXPECT_EQ(5, ild("D\213D$\000", 5));
  EXPECT_EQ(4, ild("D\213E\000", 4));
  EXPECT_EQ(4, ild("D\213G\000", 4));
  EXPECT_EQ(4, ild("D\213g\000", 4));
  EXPECT_EQ(5, ild("D\213l$\000", 5));
  EXPECT_EQ(4, ild("D\213w\000", 4));
  EXPECT_EQ(5, ild("D\213|$\000", 5));
  EXPECT_EQ(4, ild("D\213}\000", 4));
  EXPECT_EQ(7, ild("D\213\201\000\000\000\000", 7));
  EXPECT_EQ(4, ild("E\2104$", 4));
  EXPECT_EQ(3, ild("E\210\307", 3));
  EXPECT_EQ(3, ild("E\210\310", 3));
  EXPECT_EQ(3, ild("E\210\321", 3));
  EXPECT_EQ(3, ild("E\210\323", 3));
  EXPECT_EQ(3, ild("E\210\370", 3));
  EXPECT_EQ(3, ild("E\211\301", 3));
  EXPECT_EQ(3, ild("E\211\312", 3));
  EXPECT_EQ(3, ild("E\211\313", 3));
  EXPECT_EQ(3, ild("E\211\330", 3));
  EXPECT_EQ(7, ild("E\213\220\000\000\000\000", 7));
  EXPECT_EQ(4, ild("G\210,\016", 4));
  EXPECT_EQ(3, ild("Hc\022", 3));
  EXPECT_EQ(3, ild("Hc\307", 3));
  EXPECT_EQ(3, ild("Hc\310", 3));
  EXPECT_EQ(3, ild("Hc\311", 3));
  EXPECT_EQ(3, ild("Hc\320", 3));
  EXPECT_EQ(3, ild("Hc\322", 3));
  EXPECT_EQ(3, ild("Hc\366", 3));
  EXPECT_EQ(3, ild("Hc\370", 3));
  EXPECT_EQ(3, ild("H\211\002", 3));
  EXPECT_EQ(3, ild("H\211\003", 3));
  EXPECT_EQ(7, ild("H\211\005\000\000\000\000", 7));
  EXPECT_EQ(3, ild("H\211\006", 3));
  EXPECT_EQ(3, ild("H\211\007", 3));
  EXPECT_EQ(7, ild("H\211\015\000\000\000\000", 7));
  EXPECT_EQ(3, ild("H\211\020", 3));
  EXPECT_EQ(3, ild("H\211\023", 3));
  EXPECT_EQ(7, ild("H\211\025\000\000\000\000", 7));
  EXPECT_EQ(3, ild("H\211\027", 3));
  EXPECT_EQ(4, ild("H\2114$", 4));
  EXPECT_EQ(7, ild("H\2115\000\000\000\000", 7));
  EXPECT_EQ(3, ild("H\2117", 3));
  EXPECT_EQ(7, ild("H\211=\000\000\000\000", 7));
  EXPECT_EQ(4, ild("H\211C\000", 4));
  EXPECT_EQ(4, ild("H\211G\000", 4));
  EXPECT_EQ(4, ild("H\211S\000", 4));
  EXPECT_EQ(4, ild("H\211W\000", 4));
  EXPECT_EQ(4, ild("H\211w\000", 4));
  EXPECT_EQ(3, ild("H\211\301", 3));
  EXPECT_EQ(3, ild("H\211\302", 3));
  EXPECT_EQ(3, ild("H\211\303", 3));
  EXPECT_EQ(3, ild("H\211\305", 3));
  EXPECT_EQ(3, ild("H\211\306", 3));
  EXPECT_EQ(3, ild("H\211\307", 3));
  EXPECT_EQ(3, ild("H\211\310", 3));
  EXPECT_EQ(3, ild("H\211\312", 3));
  EXPECT_EQ(3, ild("H\211\315", 3));
  EXPECT_EQ(3, ild("H\211\316", 3));
  EXPECT_EQ(3, ild("H\211\320", 3));
  EXPECT_EQ(3, ild("H\211\321", 3));
  EXPECT_EQ(3, ild("H\211\323", 3));
  EXPECT_EQ(3, ild("H\211\325", 3));
  EXPECT_EQ(3, ild("H\211\326", 3));
  EXPECT_EQ(3, ild("H\211\327", 3));
  EXPECT_EQ(3, ild("H\211\331", 3));
  EXPECT_EQ(3, ild("H\211\336", 3));
  EXPECT_EQ(3, ild("H\211\337", 3));
  EXPECT_EQ(3, ild("H\211\345", 3));
  EXPECT_EQ(3, ild("H\211\347", 3));
  EXPECT_EQ(3, ild("H\211\351", 3));
  EXPECT_EQ(3, ild("H\211\356", 3));
  EXPECT_EQ(3, ild("H\211\357", 3));
  EXPECT_EQ(3, ild("H\211\360", 3));
  EXPECT_EQ(3, ild("H\211\361", 3));
  EXPECT_EQ(3, ild("H\211\363", 3));
  EXPECT_EQ(3, ild("H\211\365", 3));
  EXPECT_EQ(3, ild("H\211\367", 3));
  EXPECT_EQ(3, ild("H\211\370", 3));
  EXPECT_EQ(3, ild("H\211\372", 3));
  EXPECT_EQ(3, ild("H\211\373", 3));
  EXPECT_EQ(3, ild("H\211\375", 3));
  EXPECT_EQ(3, ild("H\211\376", 3));
  EXPECT_EQ(3, ild("H\213\000", 3));
  EXPECT_EQ(3, ild("H\213\003", 3));
  EXPECT_EQ(8, ild("H\213\004\305\000\000\000\000", 8));
  EXPECT_EQ(4, ild("H\213\004\320", 4));
  EXPECT_EQ(8, ild("H\213\004\365\000\000\000\000", 8));
  EXPECT_EQ(7, ild("H\213\005\000\000\000\000", 7));
  EXPECT_EQ(3, ild("H\213\007", 3));
  EXPECT_EQ(3, ild("H\213\013", 3));
  EXPECT_EQ(7, ild("H\213\015\000\000\000\000", 7));
  EXPECT_EQ(3, ild("H\213\022", 3));
  EXPECT_EQ(3, ild("H\213\023", 3));
  EXPECT_EQ(4, ild("H\213\024\312", 4));
  EXPECT_EQ(8, ild("H\213\024\325\000\000\000\000", 8));
  EXPECT_EQ(8, ild("H\213\024\335\000\000\000\000", 8));
  EXPECT_EQ(3, ild("H\213\027", 3));
  EXPECT_EQ(7, ild("H\213\035\000\000\000\000", 7));
  EXPECT_EQ(3, ild("H\2133", 3));
  EXPECT_EQ(4, ild("H\2134$", 4));
  EXPECT_EQ(3, ild("H\2137", 3));
  EXPECT_EQ(3, ild("H\213;", 3));
  EXPECT_EQ(7, ild("H\213=\000\000\000\000", 7));
  EXPECT_EQ(4, ild("H\213A\000", 4));
  EXPECT_EQ(4, ild("H\213C\000", 4));
  EXPECT_EQ(4, ild("H\213E\000", 4));
  EXPECT_EQ(4, ild("H\213G\000", 4));
  EXPECT_EQ(4, ild("H\213K\000", 4));
  EXPECT_EQ(4, ild("H\213O\000", 4));
  EXPECT_EQ(4, ild("H\213R\000", 4));
  EXPECT_EQ(4, ild("H\213S\000", 4));
  EXPECT_EQ(4, ild("H\213U\000", 4));
  EXPECT_EQ(4, ild("H\213W\000", 4));
  EXPECT_EQ(4, ild("H\213o\000", 4));
  EXPECT_EQ(4, ild("H\213s\000", 4));
  EXPECT_EQ(4, ild("H\213w\000", 4));
  EXPECT_EQ(4, ild("H\213{\000", 4));
  EXPECT_EQ(4, ild("H\213\177\000", 4));
  EXPECT_EQ(7, ild("H\213\200\000\000\000\000", 7));
  EXPECT_EQ(7, ild("H\213\206\000\000\000\000", 7));
  EXPECT_EQ(7, ild("H\213\207\000\000\000\000", 7));
  EXPECT_EQ(7, ild("H\213\220\000\000\000\000", 7));
  EXPECT_EQ(7, ild("H\213\221\000\000\000\000", 7));
  EXPECT_EQ(7, ild("H\213\226\000\000\000\000", 7));
  EXPECT_EQ(2, ild("H\230", 2));
  EXPECT_EQ(10, ild("H\270\000\000\000\000\000\000\000\000", 10));
  EXPECT_EQ(10, ild("H\271\000\000\000\000\000\000\000\000", 10));
  EXPECT_EQ(10, ild("H\272\000\000\000\000\000\000\000\000", 10));
  EXPECT_EQ(10, ild("H\276\000\000\000\000\000\000\000\000", 10));
  EXPECT_EQ(10, ild("H\277\000\000\000\000\000\000\000\000", 10));
  EXPECT_EQ(7, ild("H\307\003\000\000\000\000", 7));
  EXPECT_EQ(11, ild("H\307\005\000\000\000\000\000\000\000\000", 11));
  EXPECT_EQ(7, ild("H\307\007\000\000\000\000", 7));
  EXPECT_EQ(8, ild("H\307C\000\000\000\000\000", 8));
  EXPECT_EQ(8, ild("H\307G\000\000\000\000\000", 8));
  EXPECT_EQ(7, ild("H\307\300\000\000\000\000", 7));
  EXPECT_EQ(3, ild("H\323\300", 3));
  EXPECT_EQ(3, ild("H\323\340", 3));
  EXPECT_EQ(3, ild("H\323\342", 3));
  EXPECT_EQ(3, ild("H\323\350", 3));
  EXPECT_EQ(3, ild("H\323\352", 3));
  EXPECT_EQ(3, ild("Ic\367", 3));
  EXPECT_EQ(3, ild("I\211\304", 3));
  EXPECT_EQ(3, ild("I\211\305", 3));
  EXPECT_EQ(3, ild("I\211\315", 3));
  EXPECT_EQ(3, ild("I\211\320", 3));
  EXPECT_EQ(3, ild("I\211\325", 3));
  EXPECT_EQ(3, ild("I\211\344", 3));
  EXPECT_EQ(3, ild("I\211\362", 3));
  EXPECT_EQ(3, ild("I\211\364", 3));
  EXPECT_EQ(3, ild("I\211\365", 3));
  EXPECT_EQ(3, ild("I\211\366", 3));
  EXPECT_EQ(3, ild("I\211\374", 3));
  EXPECT_EQ(3, ild("I\211\375", 3));
  EXPECT_EQ(4, ild("I\213U\000", 4));
  EXPECT_EQ(3, ild("I\323\340", 3));
  EXPECT_EQ(3, ild("I\323\355", 3));
  EXPECT_EQ(8, ild("J\2134\305\000\000\000\000", 8));
  EXPECT_EQ(4, ild("L\211c\000", 4));
  EXPECT_EQ(4, ild("L\211s\000", 4));
  EXPECT_EQ(3, ild("L\211\301", 3));
  EXPECT_EQ(3, ild("L\211\306", 3));
  EXPECT_EQ(3, ild("L\211\316", 3));
  EXPECT_EQ(3, ild("L\211\320", 3));
  EXPECT_EQ(3, ild("L\211\346", 3));
  EXPECT_EQ(3, ild("L\211\347", 3));
  EXPECT_EQ(3, ild("L\211\352", 3));
  EXPECT_EQ(3, ild("L\211\356", 3));
  EXPECT_EQ(3, ild("L\211\357", 3));
  EXPECT_EQ(3, ild("L\211\372", 3));
  EXPECT_EQ(7, ild("L\213%\000\000\000\000", 7));
  EXPECT_EQ(4, ild("L\213C\000", 4));
  EXPECT_EQ(4, ild("L\213G\000", 4));
  EXPECT_EQ(4, ild("L\213c\000", 4));
  EXPECT_EQ(4, ild("L\213g\000", 4));
  EXPECT_EQ(4, ild("L\213m\000", 4));
  EXPECT_EQ(4, ild("L\213o\000", 4));
  EXPECT_EQ(4, ild("L\213w\000", 4));
  EXPECT_EQ(3, ild("Mc\300", 3));
  EXPECT_EQ(3, ild("Mc\356", 3));
  EXPECT_EQ(3, ild("M\211\303", 3));
  EXPECT_EQ(3, ild("M\211\354", 3));
  EXPECT_EQ(1, ild("S", 1));
  EXPECT_EQ(1, ild("U", 1));
  EXPECT_EQ(1, ild("X", 1));
  EXPECT_EQ(1, ild("Y", 1));
  EXPECT_EQ(1, ild("Z", 1));
  EXPECT_EQ(1, ild("[", 1));
  EXPECT_EQ(1, ild("]", 1));
  EXPECT_EQ(5, ild("fD\213G\000", 5));
  EXPECT_EQ(5, ild("fD\213o\000", 5));
  EXPECT_EQ(5, ild("fD\213u\000", 5));
  EXPECT_EQ(3, ild("f\211\002", 3));
  EXPECT_EQ(3, ild("f\211\020", 3));
  EXPECT_EQ(4, ild("f\211C\000", 4));
  EXPECT_EQ(4, ild("f\211G\000", 4));
  EXPECT_EQ(4, ild("f\211K\000", 4));
  EXPECT_EQ(4, ild("f\211O\000", 4));
  EXPECT_EQ(4, ild("f\211W\000", 4));
  EXPECT_EQ(4, ild("f\211s\000", 4));
  EXPECT_EQ(4, ild("f\211w\000", 4));
  EXPECT_EQ(4, ild("f\211{\000", 4));
  EXPECT_EQ(7, ild("f\211\201\000\000\000\000", 7));
  EXPECT_EQ(7, ild("f\211\202\000\000\000\000", 7));
  EXPECT_EQ(7, ild("f\211\220\000\000\000\000", 7));
  EXPECT_EQ(8, ild("f\213\004\205\000\000\000\000", 8));
  EXPECT_EQ(8, ild("f\213\024\255\000\000\000\000", 8));
  EXPECT_EQ(8, ild("f\213\024\325\000\000\000\000", 8));
  EXPECT_EQ(8, ild("f\213\024\355\000\000\000\000", 8));
  EXPECT_EQ(4, ild("f\213C\000", 4));
  EXPECT_EQ(4, ild("f\213G\000", 4));
  EXPECT_EQ(4, ild("f\213K\000", 4));
  EXPECT_EQ(4, ild("f\213O\000", 4));
  EXPECT_EQ(4, ild("f\213S\000", 4));
  EXPECT_EQ(4, ild("f\213W\000", 4));
  EXPECT_EQ(4, ild("f\213s\000", 4));
  EXPECT_EQ(4, ild("f\213w\000", 4));
  EXPECT_EQ(4, ild("f\213{\000", 4));
  EXPECT_EQ(7, ild("f\213\200\000\000\000\000", 7));
  EXPECT_EQ(8, ild("f\213\204\000\000\000\000\000", 8));
  EXPECT_EQ(8, ild("f\213\224\000\000\000\000\000", 8));
  EXPECT_EQ(8, ild("f\213\224-\000\000\000\000", 8));
  EXPECT_EQ(7, ild("f\213\225\000\000\000\000", 7));
  EXPECT_EQ(2, ild("f\220", 2));
  EXPECT_EQ(9, ild("f\307\005\000\000\000\000\000\000", 9));
  EXPECT_EQ(6, ild("f\307G\000\000\000", 6));
  EXPECT_EQ(9, ild("f\307\200\000\000\000\000\000\000", 9));
  EXPECT_EQ(9, ild("f\307\202\000\000\000\000\000\000", 9));
  EXPECT_EQ(2, ild("r\000", 2));
  EXPECT_EQ(2, ild("s\000", 2));
  EXPECT_EQ(2, ild("t\000", 2));
  EXPECT_EQ(2, ild("u\000", 2));
  EXPECT_EQ(2, ild("v\000", 2));
  EXPECT_EQ(2, ild("w\000", 2));
  EXPECT_EQ(2, ild("x\000", 2));
  EXPECT_EQ(2, ild("y\000", 2));
  EXPECT_EQ(2, ild("|\000", 2));
  EXPECT_EQ(2, ild("}\000", 2));
  EXPECT_EQ(2, ild("~\000", 2));
  EXPECT_EQ(2, ild("\177\000", 2));
  EXPECT_EQ(2, ild("\210\002", 2));
  EXPECT_EQ(3, ild("\210\0143", 3));
  EXPECT_EQ(2, ild("\210\020", 2));
  EXPECT_EQ(3, ild("\210C\000", 3));
  EXPECT_EQ(4, ild("\210D\024\000", 4));
  EXPECT_EQ(4, ild("\210D$\000", 4));
  EXPECT_EQ(3, ild("\210G\000", 3));
  EXPECT_EQ(3, ild("\210K\000", 3));
  EXPECT_EQ(3, ild("\210O\000", 3));
  EXPECT_EQ(3, ild("\210Q\000", 3));
  EXPECT_EQ(3, ild("\210S\000", 3));
  EXPECT_EQ(4, ild("\210T\003\000", 4));
  EXPECT_EQ(4, ild("\210T\007\000", 4));
  EXPECT_EQ(3, ild("\210W\000", 3));
  EXPECT_EQ(2, ild("\210\301", 2));
  EXPECT_EQ(2, ild("\210\302", 2));
  EXPECT_EQ(2, ild("\210\310", 2));
  EXPECT_EQ(2, ild("\210\312", 2));
  EXPECT_EQ(2, ild("\210\320", 2));
  EXPECT_EQ(2, ild("\210\321", 2));
  EXPECT_EQ(2, ild("\211\002", 2));
  EXPECT_EQ(2, ild("\211\003", 2));
  EXPECT_EQ(3, ild("\211\004$", 3));
  EXPECT_EQ(2, ild("\211\020", 2));
  EXPECT_EQ(6, ild("\211\025\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\211=\000\000\000\000", 6));
  EXPECT_EQ(3, ild("\211B\000", 3));
  EXPECT_EQ(3, ild("\211C\000", 3));
  EXPECT_EQ(4, ild("\211D$\000", 4));
  EXPECT_EQ(3, ild("\211E\000", 3));
  EXPECT_EQ(3, ild("\211G\000", 3));
  EXPECT_EQ(3, ild("\211K\000", 3));
  EXPECT_EQ(4, ild("\211L$\000", 4));
  EXPECT_EQ(3, ild("\211O\000", 3));
  EXPECT_EQ(3, ild("\211P\000", 3));
  EXPECT_EQ(4, ild("\211T$\000", 4));
  EXPECT_EQ(3, ild("\211W\000", 3));
  EXPECT_EQ(3, ild("\211X\000", 3));
  EXPECT_EQ(3, ild("\211Z\000", 3));
  EXPECT_EQ(3, ild("\211]\000", 3));
  EXPECT_EQ(3, ild("\211j\000", 3));
  EXPECT_EQ(3, ild("\211s\000", 3));
  EXPECT_EQ(4, ild("\211t$\000", 4));
  EXPECT_EQ(3, ild("\211w\000", 3));
  EXPECT_EQ(4, ild("\211|$\000", 4));
  EXPECT_EQ(6, ild("\211\202\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\211\220\000\000\000\000", 6));
  EXPECT_EQ(7, ild("\211\224$\000\000\000\000", 7));
  EXPECT_EQ(6, ild("\211\232\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\211\252\000\000\000\000", 6));
  EXPECT_EQ(2, ild("\211\300", 2));
  EXPECT_EQ(2, ild("\211\301", 2));
  EXPECT_EQ(2, ild("\211\302", 2));
  EXPECT_EQ(2, ild("\211\303", 2));
  EXPECT_EQ(2, ild("\211\305", 2));
  EXPECT_EQ(2, ild("\211\306", 2));
  EXPECT_EQ(2, ild("\211\307", 2));
  EXPECT_EQ(2, ild("\211\310", 2));
  EXPECT_EQ(2, ild("\211\313", 2));
  EXPECT_EQ(2, ild("\211\316", 2));
  EXPECT_EQ(2, ild("\211\320", 2));
  EXPECT_EQ(2, ild("\211\321", 2));
  EXPECT_EQ(2, ild("\211\323", 2));
  EXPECT_EQ(2, ild("\211\325", 2));
  EXPECT_EQ(2, ild("\211\326", 2));
  EXPECT_EQ(2, ild("\211\327", 2));
  EXPECT_EQ(2, ild("\211\330", 2));
  EXPECT_EQ(2, ild("\211\332", 2));
  EXPECT_EQ(2, ild("\211\336", 2));
  EXPECT_EQ(2, ild("\211\337", 2));
  EXPECT_EQ(2, ild("\211\350", 2));
  EXPECT_EQ(2, ild("\211\351", 2));
  EXPECT_EQ(2, ild("\211\352", 2));
  EXPECT_EQ(2, ild("\211\356", 2));
  EXPECT_EQ(2, ild("\211\360", 2));
  EXPECT_EQ(2, ild("\211\361", 2));
  EXPECT_EQ(2, ild("\211\362", 2));
  EXPECT_EQ(2, ild("\211\363", 2));
  EXPECT_EQ(2, ild("\211\365", 2));
  EXPECT_EQ(2, ild("\211\366", 2));
  EXPECT_EQ(2, ild("\211\367", 2));
  EXPECT_EQ(2, ild("\211\370", 2));
  EXPECT_EQ(2, ild("\211\371", 2));
  EXPECT_EQ(2, ild("\211\373", 2));
  EXPECT_EQ(2, ild("\211\377", 2));
  EXPECT_EQ(2, ild("\212\000", 2));
  EXPECT_EQ(3, ild("\212\004\001", 3));
  EXPECT_EQ(3, ild("\212\004\002", 3));
  EXPECT_EQ(3, ild("\212\004\006", 3));
  EXPECT_EQ(7, ild("\212\004\225\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\212\004\325\000\000\000\000", 7));
  EXPECT_EQ(2, ild("\212\006", 2));
  EXPECT_EQ(2, ild("\212\010", 2));
  EXPECT_EQ(3, ild("\212\014\001", 3));
  EXPECT_EQ(3, ild("\212\014\010", 3));
  EXPECT_EQ(7, ild("\212\014\325\000\000\000\000", 7));
  EXPECT_EQ(2, ild("\212\020", 2));
  EXPECT_EQ(3, ild("\212\024\002", 3));
  EXPECT_EQ(3, ild("\212\024\012", 3));
  EXPECT_EQ(3, ild("\212\024\021", 3));
  EXPECT_EQ(7, ild("\212\024\225\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\212\024\305\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\212\024\325\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\212\024\365\000\000\000\000", 7));
  EXPECT_EQ(3, ild("\212@\000", 3));
  EXPECT_EQ(3, ild("\212C\000", 3));
  EXPECT_EQ(3, ild("\212E\000", 3));
  EXPECT_EQ(3, ild("\212F\000", 3));
  EXPECT_EQ(3, ild("\212G\000", 3));
  EXPECT_EQ(3, ild("\212H\000", 3));
  EXPECT_EQ(3, ild("\212J\000", 3));
  EXPECT_EQ(3, ild("\212K\000", 3));
  EXPECT_EQ(3, ild("\212M\000", 3));
  EXPECT_EQ(3, ild("\212N\000", 3));
  EXPECT_EQ(3, ild("\212O\000", 3));
  EXPECT_EQ(3, ild("\212P\000", 3));
  EXPECT_EQ(3, ild("\212S\000", 3));
  EXPECT_EQ(4, ild("\212T$\000", 4));
  EXPECT_EQ(3, ild("\212W\000", 3));
  EXPECT_EQ(6, ild("\212\200\000\000\000\000", 6));
  EXPECT_EQ(7, ild("\212\204\020\000\000\000\000", 7));
  EXPECT_EQ(6, ild("\212\211\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\212\220\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\212\222\000\000\000\000", 6));
  EXPECT_EQ(2, ild("\213\000", 2));
  EXPECT_EQ(7, ild("\213\004\205\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\213\004\225\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\213\004\265\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\213\004\275\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\213\004\305\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\213\004\325\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\213\004\375\000\000\000\000", 7));
  EXPECT_EQ(2, ild("\213\006", 2));
  EXPECT_EQ(2, ild("\213\007", 2));
  EXPECT_EQ(7, ild("\213\014\205\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\213\014\215\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\213\014\265\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\213\014\275\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\213\014\315\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\213\014\325\000\000\000\000", 7));
  EXPECT_EQ(2, ild("\213\020", 2));
  EXPECT_EQ(7, ild("\213\024\205\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\213\024\225\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\213\024\255\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\213\024\305\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\213\024\315\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\213\024\325\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\213\024\355\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\213\024\365\000\000\000\000", 7));
  EXPECT_EQ(6, ild("\213\025\000\000\000\000", 6));
  EXPECT_EQ(2, ild("\213\026", 2));
  EXPECT_EQ(2, ild("\213\036", 2));
  EXPECT_EQ(2, ild("\213(", 2));
  EXPECT_EQ(7, ild("\2134\205\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\2134\315\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\2134\325\000\000\000\000", 7));
  EXPECT_EQ(3, ild("\213<$", 3));
  EXPECT_EQ(2, ild("\213?", 2));
  EXPECT_EQ(3, ild("\213@\000", 3));
  EXPECT_EQ(3, ild("\213C\000", 3));
  EXPECT_EQ(3, ild("\213E\000", 3));
  EXPECT_EQ(3, ild("\213G\000", 3));
  EXPECT_EQ(3, ild("\213H\000", 3));
  EXPECT_EQ(3, ild("\213K\000", 3));
  EXPECT_EQ(4, ild("\213L$\000", 4));
  EXPECT_EQ(3, ild("\213O\000", 3));
  EXPECT_EQ(3, ild("\213Q\000", 3));
  EXPECT_EQ(3, ild("\213S\000", 3));
  EXPECT_EQ(4, ild("\213T$\000", 4));
  EXPECT_EQ(3, ild("\213W\000", 3));
  EXPECT_EQ(3, ild("\213h\000", 3));
  EXPECT_EQ(3, ild("\213s\000", 3));
  EXPECT_EQ(4, ild("\213t$\000", 4));
  EXPECT_EQ(3, ild("\213u\000", 3));
  EXPECT_EQ(3, ild("\213w\000", 3));
  EXPECT_EQ(3, ild("\213{\000", 3));
  EXPECT_EQ(4, ild("\213|$\000", 4));
  EXPECT_EQ(3, ild("\213}\000", 3));
  EXPECT_EQ(3, ild("\213\177\000", 3));
  EXPECT_EQ(6, ild("\213\200\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\213\201\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\213\222\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\213\225\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\213\260\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\213\262\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\213\271\000\000\000\000", 6));
  EXPECT_EQ(2, ild("\260\000", 2));
  EXPECT_EQ(2, ild("\262\000", 2));
  EXPECT_EQ(5, ild("\270\000\000\000\000", 5));
  EXPECT_EQ(5, ild("\271\000\000\000\000", 5));
  EXPECT_EQ(5, ild("\272\000\000\000\000", 5));
  EXPECT_EQ(5, ild("\273\000\000\000\000", 5));
  EXPECT_EQ(5, ild("\275\000\000\000\000", 5));
  EXPECT_EQ(5, ild("\276\000\000\000\000", 5));
  EXPECT_EQ(5, ild("\277\000\000\000\000", 5));
  EXPECT_EQ(1, ild("\303", 1));
  EXPECT_EQ(3, ild("\306\001\000", 3));
  EXPECT_EQ(4, ild("\306\004\003\000", 4));
  EXPECT_EQ(7, ild("\306\005\000\000\000\000\000", 7));
  EXPECT_EQ(3, ild("\306\006\000", 3));
  EXPECT_EQ(3, ild("\306\007\000", 3));
  EXPECT_EQ(4, ild("\306@\000\000", 4));
  EXPECT_EQ(4, ild("\306B\000\000", 4));
  EXPECT_EQ(4, ild("\306C\000\000", 4));
  EXPECT_EQ(5, ild("\306D$\000\000", 5));
  EXPECT_EQ(4, ild("\306G\000\000", 4));
  EXPECT_EQ(8, ild("\306\204\016\000\000\000\000\000", 8));
  EXPECT_EQ(7, ild("\307\004\007\000\000\000\000", 7));
  EXPECT_EQ(10, ild("\307\005\000\000\000\000\000\000\000\000", 10));
  EXPECT_EQ(7, ild("\307@\000\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\307B\000\000\000\000\000", 7));
  EXPECT_EQ(8, ild("\307D$\000\000\000\000\000", 8));
  EXPECT_EQ(10, ild("\307\200\000\000\000\000\000\000\000\000", 10));
  EXPECT_EQ(11, ild("\307\204$\000\000\000\000\000\000\000\000", 11));
  EXPECT_EQ(2, ild("\322\301", 2));
  EXPECT_EQ(2, ild("\323\340", 2));
  EXPECT_EQ(2, ild("\323\342", 2));
  EXPECT_EQ(2, ild("\323\347", 2));
  EXPECT_EQ(2, ild("\340\000", 2));
  EXPECT_EQ(2, ild("\342\000", 2));
  EXPECT_EQ(5, ild("\350\000\000\000\000", 5));
  EXPECT_EQ(5, ildlegacy("\350\000\000\000\000", 5));
#ifndef DISABLE_METAL
  EXPECT_EQ(3, ildreal("\350\000\000", 3));
#endif
  EXPECT_EQ(5, ild("\350\000\203\342\000", 5));
  EXPECT_EQ(5, ild("\351\000\000\000\000", 5));
  EXPECT_EQ(5, ild("\351\000\203\340\000", 5));
  EXPECT_EQ(2, ild("\353\000", 2));
  EXPECT_EQ(2, ild("\362\256", 2));
  EXPECT_EQ(2, ild("\363\244", 2));
  EXPECT_EQ(2, ild("\363\303", 2));
  EXPECT_EQ(7, ild("\377\024\305\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\377$\305\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\377$\315\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\377$\325\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\377$\365\000\000\000\000", 7));
  EXPECT_EQ(2, ild("\377\320", 2));
  EXPECT_EQ(2, ild("\377\322", 2));
  EXPECT_EQ(2, ild("\377\340", 2));
  EXPECT_EQ(2, ild("\336\315", 2));
}

TEST(ild, test386) {
  EXPECT_EQ(3, ild("\017\224\300", 3));
  EXPECT_EQ(3, ild("\017\224\301", 3));
  EXPECT_EQ(3, ild("\017\224\302", 3));
  EXPECT_EQ(3, ild("\017\225\300", 3));
  EXPECT_EQ(3, ild("\017\225\301", 3));
  EXPECT_EQ(3, ild("\017\225\302", 3));
  EXPECT_EQ(3, ild("\017\226\300", 3));
  EXPECT_EQ(3, ild("\017\226\302", 3));
  EXPECT_EQ(3, ild("\017\227\301", 3));
  EXPECT_EQ(3, ild("\017\234\301", 3));
  EXPECT_EQ(3, ild("\017\243\320", 3));
  EXPECT_EQ(3, ild("\017\266\000", 3));
  EXPECT_EQ(8, ild("\017\266\004\225\000\000\000\000", 8));
  EXPECT_EQ(8, ild("\017\266\004\325\000\000\000\000", 8));
  EXPECT_EQ(3, ild("\017\266\007", 3));
  EXPECT_EQ(3, ild("\017\266\010", 3));
  EXPECT_EQ(4, ild("\017\266\014\010", 4));
  EXPECT_EQ(8, ild("\017\266\014\325\000\000\000\000", 8));
  EXPECT_EQ(3, ild("\017\266\017", 3));
  EXPECT_EQ(3, ild("\017\266\020", 3));
  EXPECT_EQ(3, ild("\017\266/", 3));
  EXPECT_EQ(3, ild("\017\2660", 3));
  EXPECT_EQ(4, ild("\017\26640", 4));
  EXPECT_EQ(4, ild("\017\266<\010", 4));
  EXPECT_EQ(3, ild("\017\266?", 3));
  EXPECT_EQ(4, ild("\017\266@\000", 4));
  EXPECT_EQ(4, ild("\017\266A\000", 4));
  EXPECT_EQ(4, ild("\017\266C\000", 4));
  EXPECT_EQ(5, ild("\017\266D7\000", 5));
  EXPECT_EQ(4, ild("\017\266F\000", 4));
  EXPECT_EQ(4, ild("\017\266G\000", 4));
  EXPECT_EQ(4, ild("\017\266H\000", 4));
  EXPECT_EQ(4, ild("\017\266K\000", 4));
  EXPECT_EQ(4, ild("\017\266O\000", 4));
  EXPECT_EQ(4, ild("\017\266P\000", 4));
  EXPECT_EQ(4, ild("\017\266R\000", 4));
  EXPECT_EQ(4, ild("\017\266S\000", 4));
  EXPECT_EQ(4, ild("\017\266W\000", 4));
  EXPECT_EQ(4, ild("\017\266X\000", 4));
  EXPECT_EQ(4, ild("\017\266_\000", 4));
  EXPECT_EQ(4, ild("\017\266p\000", 4));
  EXPECT_EQ(4, ild("\017\266s\000", 4));
  EXPECT_EQ(5, ild("\017\266t$\000", 5));
  EXPECT_EQ(4, ild("\017\266{\000", 4));
  EXPECT_EQ(4, ild("\017\266}\000", 4));
  EXPECT_EQ(4, ild("\017\266\177\000", 4));
  EXPECT_EQ(7, ild("\017\266\200\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\017\266\202\000\000\000\000", 7));
  EXPECT_EQ(8, ild("\017\266\204\022\000\000\000\000", 8));
  EXPECT_EQ(7, ild("\017\266\207\000\000\000\000", 7));
  EXPECT_EQ(8, ild("\017\266\214\020\000\000\000\000", 8));
  EXPECT_EQ(8, ild("\017\266\224\021\000\000\000\000", 8));
  EXPECT_EQ(8, ild("\017\266\234$\000\000\000\000", 8));
  EXPECT_EQ(3, ild("\017\266\300", 3));
  EXPECT_EQ(3, ild("\017\266\301", 3));
  EXPECT_EQ(3, ild("\017\266\302", 3));
  EXPECT_EQ(3, ild("\017\266\310", 3));
  EXPECT_EQ(3, ild("\017\266\311", 3));
  EXPECT_EQ(3, ild("\017\266\312", 3));
  EXPECT_EQ(3, ild("\017\266\320", 3));
  EXPECT_EQ(3, ild("\017\266\322", 3));
  EXPECT_EQ(3, ild("\017\266\350", 3));
  EXPECT_EQ(3, ild("\017\266\360", 3));
  EXPECT_EQ(3, ild("\017\266\361", 3));
  EXPECT_EQ(3, ild("\017\266\362", 3));
  EXPECT_EQ(3, ild("\017\266\371", 3));
  EXPECT_EQ(3, ild("\017\267\000", 3));
  EXPECT_EQ(3, ild("\017\2679", 3));
  EXPECT_EQ(4, ild("\017\267B\000", 4));
  EXPECT_EQ(4, ild("\017\267E\000", 4));
  EXPECT_EQ(4, ild("\017\267F\000", 4));
  EXPECT_EQ(4, ild("\017\267G\000", 4));
  EXPECT_EQ(4, ild("\017\267P\000", 4));
  EXPECT_EQ(4, ild("\017\267W\000", 4));
  EXPECT_EQ(5, ild("\017\267t$\000", 5));
  EXPECT_EQ(4, ild("\017\267x\000", 4));
  EXPECT_EQ(7, ild("\017\267\200\000\000\000\000", 7));
  EXPECT_EQ(8, ild("\017\267\204\000\000\000\000\000", 8));
  EXPECT_EQ(3, ild("\017\267\300", 3));
  EXPECT_EQ(3, ild("\017\267\307", 3));
  EXPECT_EQ(3, ild("\017\267\322", 3));
  EXPECT_EQ(3, ild("\017\267\366", 3));
  EXPECT_EQ(3, ild("\017\267\372", 3));
  EXPECT_EQ(4, ild("\017\272\345\000", 4));
  EXPECT_EQ(8, ild("\017\276\004\225\000\000\000\000", 8));
  EXPECT_EQ(8, ild("\017\276\004\325\000\000\000\000", 8));
  EXPECT_EQ(8, ild("\017\276\014\325\000\000\000\000", 8));
  EXPECT_EQ(4, ild("\017\276A\000", 4));
  EXPECT_EQ(4, ild("\017\276F\000", 4));
  EXPECT_EQ(4, ild("\017\276G\000", 4));
  EXPECT_EQ(4, ild("\017\276J\000", 4));
  EXPECT_EQ(4, ild("\017\276N\000", 4));
  EXPECT_EQ(4, ild("\017\276O\000", 4));
  EXPECT_EQ(4, ild("\017\276V\000", 4));
  EXPECT_EQ(7, ild("\017\276\200\000\000\000\000", 7));
  EXPECT_EQ(7, ild("\017\276\201\000\000\000\000", 7));
  EXPECT_EQ(8, ild("\017\276\204\022\000\000\000\000", 8));
  EXPECT_EQ(3, ild("\017\276\370", 3));
  EXPECT_EQ(3, ild("\017\277\307", 3));
  EXPECT_EQ(3, ild("\017\277\370", 3));
  EXPECT_EQ(4, ild("@\017\224\306", 4));
  EXPECT_EQ(4, ild("@\017\224\307", 4));
  EXPECT_EQ(4, ild("@\017\236\305", 4));
  EXPECT_EQ(4, ild("@\017\266\305", 4));
  EXPECT_EQ(4, ild("@\017\266\307", 4));
  EXPECT_EQ(4, ild("@\017\266\315", 4));
  EXPECT_EQ(4, ild("@\017\266\316", 4));
  EXPECT_EQ(4, ild("@\017\266\325", 4));
  EXPECT_EQ(4, ild("@\017\266\366", 4));
  EXPECT_EQ(4, ild("@\017\266\377", 4));
  EXPECT_EQ(4, ild("@\017\276\307", 4));
  EXPECT_EQ(4, ild("A\017\224\300", 4));
  EXPECT_EQ(4, ild("A\017\225\304", 4));
  EXPECT_EQ(5, ild("A\017\266,\020", 5));
  EXPECT_EQ(5, ild("A\017\2664\000", 5));
  EXPECT_EQ(6, ild("A\017\266D$\000", 6));
  EXPECT_EQ(6, ild("A\017\266|,\000", 6));
  EXPECT_EQ(6, ild("A\017\267D$\000", 6));
  EXPECT_EQ(4, ild("D\017\266\007", 4));
  EXPECT_EQ(4, ild("D\017\266 ", 4));
  EXPECT_EQ(5, ild("D\017\266$0", 5));
  EXPECT_EQ(4, ild("D\017\266'", 4));
  EXPECT_EQ(5, ild("D\017\266,\010", 5));
  EXPECT_EQ(4, ild("D\017\266/", 4));
  EXPECT_EQ(5, ild("D\017\266G\000", 5));
  EXPECT_EQ(5, ild("D\017\266k\000", 5));
  EXPECT_EQ(5, ild("D\017\266u\000", 5));
  EXPECT_EQ(5, ild("E\017\266\014\000", 5));
  EXPECT_EQ(5, ild("E\017\2664$", 5));
  EXPECT_EQ(5, ild("E\017\266u\000", 5));
  EXPECT_EQ(4, ild("E\017\266\300", 4));
  EXPECT_EQ(4, ild("E\017\267\300", 4));
  EXPECT_EQ(4, ild("H\017\243\316", 4));
  EXPECT_EQ(4, ild("H\017\243\320", 4));
  EXPECT_EQ(4, ild("H\017\243\321", 4));
  EXPECT_EQ(9, ild("H\017\276\004\325\000\000\000\000", 9));
  EXPECT_EQ(4, ild("H\017\276\022", 4));
  EXPECT_EQ(4, ild("H\017\276\307", 4));
  EXPECT_EQ(4, ild("H\017\276\366", 4));
  EXPECT_EQ(4, ild("H\017\277\022", 4));
  EXPECT_EQ(4, ild("H\017\277\307", 4));
  EXPECT_EQ(4, ild("H\017\277\366", 4));
  EXPECT_EQ(5, ild("f@\017\276\307", 5));
  EXPECT_EQ(2, ild("\363\253", 2));
}

TEST(ild, testBinary) {
  EXPECT_EQ(2, ild("\000\000", 2));
  EXPECT_EQ(6, ild("\000\270\000\000\000\000", 6));
  EXPECT_EQ(2, ild("\000\301", 2));
  EXPECT_EQ(2, ild("\000\377", 2));
  EXPECT_EQ(6, ild("\001\260\000\000\000\000", 6));
  EXPECT_EQ(2, ild("\001\300", 2));
  EXPECT_EQ(2, ild("\001\301", 2));
  EXPECT_EQ(2, ild("\001\302", 2));
  EXPECT_EQ(2, ild("\001\305", 2));
  EXPECT_EQ(2, ild("\001\310", 2));
  EXPECT_EQ(2, ild("\001\311", 2));
  EXPECT_EQ(2, ild("\001\320", 2));
  EXPECT_EQ(2, ild("\001\322", 2));
  EXPECT_EQ(2, ild("\001\326", 2));
  EXPECT_EQ(2, ild("\001\360", 2));
  EXPECT_EQ(2, ild("\001\376", 2));
  EXPECT_EQ(3, ild("\017\257\302", 3));
  EXPECT_EQ(2, ild("\031\300", 2));
  EXPECT_EQ(2, ild(")\302", 2));
  EXPECT_EQ(2, ild(")\303", 2));
  EXPECT_EQ(2, ild(")\305", 2));
  EXPECT_EQ(2, ild(")\335", 2));
  EXPECT_EQ(2, ild(")\350", 2));
  EXPECT_EQ(3, ild("8W\000", 3));
  EXPECT_EQ(2, ild("9\301", 2));
  EXPECT_EQ(2, ild("9\302", 2));
  EXPECT_EQ(2, ild("9\303", 2));
  EXPECT_EQ(2, ild("9\305", 2));
  EXPECT_EQ(2, ild("9\312", 2));
  EXPECT_EQ(2, ild("9\320", 2));
  EXPECT_EQ(2, ild("9\330", 2));
  EXPECT_EQ(2, ild("9\353", 2));
  EXPECT_EQ(2, ild("9\360", 2));
  EXPECT_EQ(2, ild("9\361", 2));
  EXPECT_EQ(2, ild("9\367", 2));
  EXPECT_EQ(2, ild("9\371", 2));
  EXPECT_EQ(3, ild(":C\000", 3));
  EXPECT_EQ(3, ild(":K\000", 3));
  EXPECT_EQ(3, ild(":S\000", 3));
  EXPECT_EQ(2, ild("<\000", 2));
  EXPECT_EQ(5, ild("=\000\000\000\000", 5));
  EXPECT_EQ(3, ild("@8\361", 3));
  EXPECT_EQ(4, ild("@\200\376\000", 4));
  EXPECT_EQ(4, ild("@\200\377\000", 4));
  EXPECT_EQ(3, ild("A)\314", 3));
  EXPECT_EQ(3, ild("A8\355", 3));
  EXPECT_EQ(3, ild("A9\301", 3));
  EXPECT_EQ(3, ild("A9\304", 3));
  EXPECT_EQ(3, ild("A9\306", 3));
  EXPECT_EQ(3, ild("A9\320", 3));
  EXPECT_EQ(3, ild("A9\321", 3));
  EXPECT_EQ(3, ild("A9\335", 3));
  EXPECT_EQ(3, ild("A9\354", 3));
  EXPECT_EQ(3, ild("A9\356", 3));
  EXPECT_EQ(3, ild("A9\365", 3));
  EXPECT_EQ(5, ild("A\200<\000\000", 5));
  EXPECT_EQ(6, ild("A\200|$\000\000", 6));
  EXPECT_EQ(4, ild("A\200\370\000", 4));
  EXPECT_EQ(4, ild("A\200\371\000", 4));
  EXPECT_EQ(7, ild("A\201\370\000\000\000\000", 7));
  EXPECT_EQ(4, ild("A\203\370\000", 4));
  EXPECT_EQ(4, ild("A\203\371\000", 4));
  EXPECT_EQ(4, ild("A\203\373\000", 4));
  EXPECT_EQ(4, ild("A\203\374\000", 4));
  EXPECT_EQ(4, ild("A\203\375\000", 4));
  EXPECT_EQ(4, ild("A\203\376\000", 4));
  EXPECT_EQ(3, ild("A\377\301", 3));
  EXPECT_EQ(3, ild("A\377\302", 3));
  EXPECT_EQ(3, ild("A\377\304", 3));
  EXPECT_EQ(3, ild("A\377\306", 3));
  EXPECT_EQ(3, ild("A\377\307", 3));
  EXPECT_EQ(3, ild("A\377\310", 3));
  EXPECT_EQ(3, ild("A\377\317", 3));
  EXPECT_EQ(3, ild("D\001\310", 3));
  EXPECT_EQ(3, ild("D\001\350", 3));
  EXPECT_EQ(3, ild("D)\300", 3));
  EXPECT_EQ(3, ild("D)\321", 3));
  EXPECT_EQ(3, ild("D)\335", 3));
  EXPECT_EQ(3, ild("D)\341", 3));
  EXPECT_EQ(3, ild("D8\301", 3));
  EXPECT_EQ(3, ild("D9\302", 3));
  EXPECT_EQ(3, ild("D9\305", 3));
  EXPECT_EQ(3, ild("D9\307", 3));
  EXPECT_EQ(3, ild("D9\311", 3));
  EXPECT_EQ(3, ild("D9\341", 3));
  EXPECT_EQ(3, ild("D9\343", 3));
  EXPECT_EQ(3, ild("D9\345", 3));
  EXPECT_EQ(3, ild("D9\350", 3));
  EXPECT_EQ(3, ild("D9\363", 3));
  EXPECT_EQ(3, ild("E\001\342", 3));
  EXPECT_EQ(3, ild("E\001\344", 3));
  EXPECT_EQ(3, ild("E)\304", 3));
  EXPECT_EQ(3, ild("E9\356", 3));
  EXPECT_EQ(3, ild("E9\357", 3));
  EXPECT_EQ(3, ild("E9\364", 3));
  EXPECT_EQ(3, ild("E9\376", 3));
  EXPECT_EQ(3, ild("H\001\300", 3));
  EXPECT_EQ(3, ild("H\001\301", 3));
  EXPECT_EQ(3, ild("H\001\302", 3));
  EXPECT_EQ(3, ild("H\001\306", 3));
  EXPECT_EQ(3, ild("H\001\310", 3));
  EXPECT_EQ(3, ild("H\001\312", 3));
  EXPECT_EQ(3, ild("H\001\320", 3));
  EXPECT_EQ(3, ild("H\001\321", 3));
  EXPECT_EQ(3, ild("H\001\322", 3));
  EXPECT_EQ(3, ild("H\001\336", 3));
  EXPECT_EQ(3, ild("H\001\337", 3));
  EXPECT_EQ(3, ild("H\001\357", 3));
  EXPECT_EQ(3, ild("H\001\360", 3));
  EXPECT_EQ(3, ild("H\001\362", 3));
  EXPECT_EQ(3, ild("H\001\370", 3));
  EXPECT_EQ(4, ild("H\003G\000", 4));
  EXPECT_EQ(4, ild("H\003S\000", 4));
  EXPECT_EQ(6, ild("H\005\000\000\000\000", 6));
  EXPECT_EQ(4, ild("H\017\257\310", 4));
  EXPECT_EQ(4, ild("H\017\257\312", 4));
  EXPECT_EQ(4, ild("H\017\257\320", 4));
  EXPECT_EQ(3, ild("H)\332", 3));
  EXPECT_EQ(6, ild("H-\000\000\000\000", 6));
  EXPECT_EQ(3, ild("H9\301", 3));
  EXPECT_EQ(3, ild("H9\302", 3));
  EXPECT_EQ(3, ild("H9\307", 3));
  EXPECT_EQ(3, ild("H9\310", 3));
  EXPECT_EQ(3, ild("H9\312", 3));
  EXPECT_EQ(3, ild("H9\320", 3));
  EXPECT_EQ(3, ild("H9\326", 3));
  EXPECT_EQ(3, ild("H9\330", 3));
  EXPECT_EQ(3, ild("H9\360", 3));
  EXPECT_EQ(3, ild("H9\361", 3));
  EXPECT_EQ(3, ild("H9\362", 3));
  EXPECT_EQ(3, ild("H9\370", 3));
  EXPECT_EQ(6, ild("H=\000\000\000\000", 6));
  EXPECT_EQ(7, ild("H\201\304\000\000\000\000", 7));
  EXPECT_EQ(7, ild("H\201\353\000\000\000\000", 7));
  EXPECT_EQ(7, ild("H\201\354\000\000\000\000", 7));
  EXPECT_EQ(7, ild("H\201\356\000\000\000\000", 7));
  EXPECT_EQ(7, ild("H\201\377\000\000\000\000", 7));
  EXPECT_EQ(5, ild("H\203\177\000\000", 5));
  EXPECT_EQ(4, ild("H\203\300\000", 4));
  EXPECT_EQ(4, ild("H\203\302\000", 4));
  EXPECT_EQ(4, ild("H\203\303\000", 4));
  EXPECT_EQ(4, ild("H\203\304\000", 4));
  EXPECT_EQ(4, ild("H\203\350\000", 4));
  EXPECT_EQ(4, ild("H\203\353\000", 4));
  EXPECT_EQ(4, ild("H\203\354\000", 4));
  EXPECT_EQ(4, ild("H\203\370\000", 4));
  EXPECT_EQ(4, ild("H\203\371\000", 4));
  EXPECT_EQ(4, ild("H\203\372\000", 4));
  EXPECT_EQ(4, ild("H\203\373\000", 4));
  EXPECT_EQ(4, ild("H\203\376\000", 4));
  EXPECT_EQ(4, ild("H\203\377\000", 4));
  EXPECT_EQ(3, ild("H\367\333", 3));
  EXPECT_EQ(3, ild("H\367\361", 3));
  EXPECT_EQ(3, ild("H\367\366", 3));
  EXPECT_EQ(3, ild("H\367\367", 3));
  EXPECT_EQ(3, ild("H\377\300", 3));
  EXPECT_EQ(3, ild("H\377\301", 3));
  EXPECT_EQ(3, ild("H\377\302", 3));
  EXPECT_EQ(3, ild("H\377\305", 3));
  EXPECT_EQ(3, ild("H\377\306", 3));
  EXPECT_EQ(3, ild("H\377\307", 3));
  EXPECT_EQ(3, ild("H\377\310", 3));
  EXPECT_EQ(3, ild("H\377\311", 3));
  EXPECT_EQ(3, ild("I\001\321", 3));
  EXPECT_EQ(3, ild("I)\302", 3));
  EXPECT_EQ(3, ild("I\367\334", 3));
  EXPECT_EQ(3, ild("I\367\361", 3));
  EXPECT_EQ(3, ild("I\377\300", 3));
  EXPECT_EQ(3, ild("I\377\305", 3));
  EXPECT_EQ(3, ild("L\001\300", 3));
  EXPECT_EQ(3, ild("L\001\340", 3));
  EXPECT_EQ(3, ild("L\001\350", 3));
  EXPECT_EQ(4, ild("L\003O\000", 4));
  EXPECT_EQ(3, ild("L)\300", 3));
  EXPECT_EQ(3, ild("f9\312", 3));
  EXPECT_EQ(3, ild("f9\320", 3));
  EXPECT_EQ(4, ild("f=\000\000", 4));
  EXPECT_EQ(5, ild("f\201\302\000\000", 5));
  EXPECT_EQ(5, ild("f\201\372\000\000", 5));
  EXPECT_EQ(5, ild("f\201\375\000\000", 5));
  EXPECT_EQ(5, ild("f\203x\000\000", 5));
  EXPECT_EQ(4, ild("f\203\370\000", 4));
  EXPECT_EQ(4, ild("f\203\371\000", 4));
  EXPECT_EQ(4, ild("f\203\372\000", 4));
  EXPECT_EQ(3, ild("\2008\000", 3));
  EXPECT_EQ(7, ild("\200=\000\000\000\000\000", 7));
  EXPECT_EQ(4, ild("\200x\000\000", 4));
  EXPECT_EQ(4, ild("\200z\000\000", 4));
  EXPECT_EQ(4, ild("\200{\000\000", 4));
  EXPECT_EQ(4, ild("\200}\000\000", 4));
  EXPECT_EQ(4, ild("\200\177\000\000", 4));
  EXPECT_EQ(3, ild("\200\371\000", 3));
  EXPECT_EQ(3, ild("\200\372\000", 3));
  EXPECT_EQ(6, ild("\201\353\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\201\372\000\000\000\000", 6));
  EXPECT_EQ(6, ild("\201\377\000\000\000\000", 6));
  EXPECT_EQ(4, ild("\203<$\000", 4));
  EXPECT_EQ(8, ild("\203<\325\000\000\000\000\000", 8));
  EXPECT_EQ(7, ild("\203=\000\000\000\000\000", 7));
  EXPECT_EQ(4, ild("\203x\000\000", 4));
  EXPECT_EQ(4, ild("\203}\000\000", 4));
  EXPECT_EQ(4, ild("\203\177\000\000", 4));
  EXPECT_EQ(7, ild("\203\270\000\000\000\000\000", 7));
  EXPECT_EQ(3, ild("\203\301\000", 3));
  EXPECT_EQ(3, ild("\203\302\000", 3));
  EXPECT_EQ(3, ild("\203\307\000", 3));
  EXPECT_EQ(3, ild("\203\350\000", 3));
  EXPECT_EQ(3, ild("\203\351\000", 3));
  EXPECT_EQ(3, ild("\203\352\000", 3));
  EXPECT_EQ(3, ild("\203\370\000", 3));
  EXPECT_EQ(3, ild("\203\371\000", 3));
  EXPECT_EQ(3, ild("\203\372\000", 3));
  EXPECT_EQ(3, ild("\203\373\000", 3));
  EXPECT_EQ(3, ild("\203\375\000", 3));
  EXPECT_EQ(3, ild("\203\376\000", 3));
  EXPECT_EQ(3, ild("\203\377\000", 3));
  EXPECT_EQ(3, ild("\367u\000", 3));
  EXPECT_EQ(2, ild("\367\333", 2));
  EXPECT_EQ(3, ild("\376C\000", 3));
  EXPECT_EQ(2, ild("\376\310", 2));
  EXPECT_EQ(2, ild("\376\311", 2));
  EXPECT_EQ(2, ild("\376\312", 2));
  EXPECT_EQ(2, ild("\377\300", 2));
  EXPECT_EQ(2, ild("\377\301", 2));
  EXPECT_EQ(2, ild("\377\302", 2));
  EXPECT_EQ(2, ild("\377\303", 2));
  EXPECT_EQ(2, ild("\377\305", 2));
  EXPECT_EQ(2, ild("\377\306", 2));
  EXPECT_EQ(2, ild("\377\310", 2));
  EXPECT_EQ(2, ild("\377\312", 2));
  EXPECT_EQ(2, ild("\377\316", 2));
}

TEST(ild, testWideNops) {
  EXPECT_EQ(1, ild("\220", 1));
  EXPECT_EQ(2, ild("f\220", 2));
  EXPECT_EQ(3, ild("\017\037\000", 3));
  EXPECT_EQ(4, ild("\017\037@\000", 4));
  EXPECT_EQ(5, ild("\017\037D\000\000", 5));
  EXPECT_EQ(6, ild("f\017\037D\000\000", 6));
  EXPECT_EQ(7, ild("\017\037\200\000\000\000\000", 7));
  EXPECT_EQ(8, ild("\017\037\204\000\000\000\000\000", 8));
  EXPECT_EQ(9, ild("f\017\037\204\000\000\000\000\000", 9));
}

#ifndef DISABLE_BMI2

TEST(ild, mulx) {
  // mulx %rbx,%rdx,%rcx
  char code[15] = "\xc4\xe2\xeb\xf6\xcb";
  EXPECT_EQ(0, DecodeInstruction(&xedd, code, 15, XED_MODE_LONG));
  EXPECT_EQ(5, xedd.length);
  EXPECT_EQ(2 << 8 | 0xf6, Mopcode(xedd.op.rde));
  EXPECT_EQ(3, ModrmMod(xedd.op.rde));  // register operand
  EXPECT_TRUE(Rexw(xedd.op.rde));       // 64-bit
  EXPECT_EQ(1, ModrmReg(xedd.op.rde));  // rcx (arg1)
  EXPECT_EQ(2, Vreg(xedd.op.rde));      // rdx (arg2)
  EXPECT_EQ(3, ModrmRm(xedd.op.rde));   // rbx (arg3)
}

TEST(ild, shlx) {
  // mulx %rbx,%rdx,%rcx
  char code[15] = "\xc4\xe2\x71\xf7\xd8";
  EXPECT_EQ(0, DecodeInstruction(&xedd, code, 15, XED_MODE_LONG));
  EXPECT_EQ(5, xedd.length);
  EXPECT_EQ(2 << 8 | 0xf7, Mopcode(xedd.op.rde));
  EXPECT_EQ(3, ModrmMod(xedd.op.rde));  // register operand
  EXPECT_TRUE(!Rexw(xedd.op.rde));      // 32-bit
  EXPECT_EQ(3, ModrmReg(xedd.op.rde));  //
  EXPECT_EQ(1, Vreg(xedd.op.rde));      //
  EXPECT_EQ(0, ModrmRm(xedd.op.rde));   //
  EXPECT_TRUE(Osz(xedd.op.rde));        //
}

#endif /* DISABLE_BMI2 */
